home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
ARASAN_S.ZIP
/
DISPLAY.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-05
|
14KB
|
481 lines
// Copyright 1994 by Jon Dart. All Rights Reserved.
#include "display.h"
#include "square.h"
#include "constant.h"
#include <wpwin.h>
#include <string.h>
#include <stdio.h>
static WPBitmap *pawn_bitmap = NULL;
static WPBitmap *pawn_outline = NULL;
static WPBitmap *knight_bitmap = NULL;
static WPBitmap *knight_outline = NULL;
static WPBitmap *bishop_bitmap = NULL;
static WPBitmap *bishop_outline = NULL;
static WPBitmap *rook_bitmap = NULL;
static WPBitmap *rook_outline = NULL;
static WPBitmap *queen_bitmap = NULL;
static WPBitmap *queen_outline = NULL;
static WPBitmap *king_bitmap = NULL;
static WPBitmap *king_outline = NULL;
#define DARK_SQUARE_COLOR RGB(0,0x80,0)
#define LIGHT_SQUARE_COLOR RGB(0,0xFF,0)
#define STATUS_AREA_WIDTH 80
#define TEXT_OFFSET 75 /* from right edge */
#define TIME_Y 80
#define MOVE_Y 170
#define PLY_Y 210
int Display::spacing = 0;
Display::Display( WPWin *pWin, const WPRect &initial_size )
: turned(False)
{
TEXTMETRIC my_tm;
WPWinDC dc = pWin;
GetTextMetrics(dc(),&my_tm);
char_width = my_tm.tmAveCharWidth;
max_char_width = my_tm.tmMaxCharWidth;
char_height = my_tm.tmHeight;
spacing = my_tm.tmHeight + my_tm.tmExternalLeading;
vertical_border_width = char_width + 6;
horiz_border_height = char_height + 4;
set_size((WPRect)initial_size);
if (pawn_bitmap)
return;
pawn_bitmap = new WPBitmap("PAWN_BITMAP");
pawn_outline = new WPBitmap("PAWN_OUTLINE");
knight_bitmap = new WPBitmap("KNIGHT_BITMAP");
knight_outline = new WPBitmap("KNIGHT_OUTLINE");
bishop_bitmap = new WPBitmap("BISHOP_BITMAP");
bishop_outline = new WPBitmap("BISHOP_OUTLINE");
rook_bitmap = new WPBitmap("ROOK_BITMAP");
rook_outline = new WPBitmap("ROOK_OUTLINE");
queen_bitmap = new WPBitmap("QUEEN_BITMAP");
queen_outline = new WPBitmap("QUEEN_OUTLINE");
king_bitmap = new WPBitmap("KING_BITMAP");
king_outline = new WPBitmap("KING_OUTLINE");
}
Display::~Display()
{
delete king_bitmap;
delete king_outline;
delete queen_bitmap;
delete queen_outline;
delete rook_bitmap;
delete rook_outline;
delete bishop_bitmap;
delete bishop_outline;
delete knight_bitmap;
delete knight_outline;
delete pawn_bitmap;
delete pawn_outline;
}
void Display::draw_piece(WPDevContext &dc,
WPRect &square,WPBitmap *bitmap,WPRect &src_rect,
const ColorType color,WPBitmap *outline)
{
// make dest square a little smaller, to avoid clobbering
// black space between squares:
WPRect new_area(square.left()+1,square.top()+1,
square.right()-1,square.bottom()-1);
if (color == Black)
{
WPMemDC memdc(&dc, bitmap);
dc.stretchBlt(new_area,memdc,src_rect,MERGECOPY);
}
else
{
{
WPMemDC memdc(&dc, bitmap);
dc.stretchBlt(new_area,memdc,src_rect,MERGEPAINT);
}
if (outline)
{
WPMemDC memdc(&dc,outline);
dc.stretchBlt(new_area,memdc,src_rect,SRCAND);
}
}
}
void Display::draw_piece( WPDevContext &dc, WPRect &square, const Piece &piece)
{
WPRect src_rect(1,1,62,62);
switch(piece.Type())
{
case Piece::Pawn:
{
draw_piece(dc,square,pawn_bitmap,src_rect,piece.Color(),
pawn_outline);
break;
}
case Piece::Rook:
{
draw_piece(dc,square,rook_bitmap,src_rect,piece.Color(),
rook_outline);
break;
}
case Piece::Knight:
{
draw_piece(dc,square,knight_bitmap,src_rect,piece.Color(),
knight_outline);
break;
}
case Piece::Bishop:
{
draw_piece(dc,square,bishop_bitmap,src_rect,piece.Color(),
bishop_outline);
break;
}
case Piece::Queen:
{
draw_piece(dc,square,queen_bitmap,src_rect,piece.Color(),
queen_outline);
break;
}
case Piece::King:
{
draw_piece(dc,square,king_bitmap,src_rect,piece.Color(),
king_outline);
break;
}
default:
break;
}
}
void Display::set_size(WPRect &size)
{
display_area = size;
width = size.width();
height = size.height() - horiz_border_height;
square_height = height/8;
square_width = (width - STATUS_AREA_WIDTH - vertical_border_width) / 8;
}
void Display::draw_board( WPDevContext &dc, const Board &board,
const WPRect *drawArea)
{
HRGN drawRegion = CreateRectRgnIndirect((RECT *)drawArea);
int vert_incr, vert_start, horiz_incr, horiz_start;
if (turned)
{
vert_incr = -square_height;
vert_start = 7*square_height;
horiz_incr = -square_width;
horiz_start = 7*square_width;
}
else
{
vert_incr = square_height;
vert_start = horiz_start = 0;
horiz_incr = square_width;
}
int vert = vert_start;
int horiz;
const int right_edge = square_width*8;
const int bottom_edge = square_height*8;
HRGN paintRegion = CreateRectRgn(0,0,0,0);
int mono = dc.getCap(NUMCOLORS) <= 2;
for (int i = 0; i < 8; i++)
{
horiz = horiz_start;
// draw text in vertical border:
int text_start = (i*square_height) + square_height/2 - char_height/2;
RECT rc;
SetRect(&rc,right_edge+3, text_start,
right_edge+vertical_border_width-3,
text_start+max_char_width);
char border_text[1];
*border_text = (turned) ? '1' + i : '8' - i;
DrawText(dc(),border_text,1,&rc,DT_LEFT);
// draw text in horizontal border:
text_start = (i*square_width) + square_width/2 - char_width/2;
SetRect(&rc, text_start,bottom_edge+2,text_start+max_char_width,
bottom_edge+horiz_border_height);
*border_text = (turned) ? 'H' - i : 'A' + i;
DrawText(dc(),border_text,1,&rc,DT_LEFT);
for (int j = 0; j < 8; j++)
{
Square sq(j+1,i+1,Black);
WPRect square(WPPoint(horiz,vert),
WPPoint(horiz+square_width,vert+square_height));
HRGN squareRegion = CreateRectRgnIndirect((RECT*)&square);
if (CombineRgn(paintRegion,squareRegion,drawRegion,RGN_AND)
!= NULLREGION)
{
if ((j + i) % 2)
{
if (mono)
dc.setBrushHatch(COLOR_BLACK,HS_DIAGCROSS);
else
dc.setBrush(DARK_SQUARE_COLOR);
}
else
{
if (mono)
dc.setBrush(COLOR_WHITE);
else
dc.setBrush(LIGHT_SQUARE_COLOR);
}
dc.rectangle(square);
Piece piece(board[sq]);
if (!piece.IsEmpty())
{
draw_piece(dc,square,piece);
}
}
horiz += horiz_incr;
DeleteObject(squareRegion);
}
vert += vert_incr;
}
show_side(dc,board.Side());
DeleteObject(paintRegion);
DeleteObject(drawRegion);
}
void Display::square_rect(const Square &sq, WPRect &out )
{
WPRect size = get_size();
int rank = sq.Rank(Black);
int file = sq.File();
if (turned)
{
rank = 9-rank;
file = 9-file;
}
WPPoint orig(square_width*(file-1),square_height*(rank-1));
WPPoint end(square_width*file,square_height*rank);
out = WPRect(orig,end);
}
void Display::draw_piece( WPDevContext &dc, const Square &loc, const Piece &p )
{
WPRect area;
square_rect(loc,area);
draw_piece(dc,area,p);
}
void Display::draw_square( WPDevContext &dc, const Square &loc )
{
WPRect area;
square_rect(loc,area);
int mono = dc.getCap(NUMCOLORS) <= 2;
if ((loc.Rank(Black) + loc.File()) % 2)
{
if (mono)
dc.setBrushHatch(COLOR_BLACK,HS_DIAGCROSS);
else
dc.setBrush(DARK_SQUARE_COLOR);
}
else
{
if (mono)
dc.setBrush(COLOR_WHITE);
else
dc.setBrush(LIGHT_SQUARE_COLOR);
}
dc.rectangle(area);
}
void Display::highlight_square( WPDevContext &, const Square & )
{
// unimplemented
}
void Display::unhighlight_square( WPDevContext &, const Square & )
{
// unimplemented
}
void Display::set_turned(Boolean turnit)
{
turned = turnit;
}
Square Display::mouse_loc( WPPoint &p)
{
int x,y;
x = (p.x/square_width)+1;
if (turned)
x = 9-x;
y = (p.y/square_height)+1;
if (x > 8 || y > 8)
return Square(0);
else
return Square(x,y,turned ? White : Black);
}
void Display::show_side( WPDevContext &dc, const ColorType side )
{
static char *wstr = "WHITE to move";
static char *bstr = "BLACK to move";
RECT rcText;
int start = width - TEXT_OFFSET;
SetRect(&rcText,start,20,width-5,80);
DrawText(dc(),(side == White) ? wstr : bstr,
lstrlen(wstr), &rcText, DT_LEFT | DT_WORDBREAK);
}
void Display::show_move( WPDevContext &dc, const char *move_image,
int number )
{
RECT rcText;
int start = width - TEXT_OFFSET;
SetRect(&rcText,start,MOVE_Y,start+width-5,
MOVE_Y+spacing);
char text[80];
// erase any previous text:
HBRUSH brush = GetStockObject(WHITE_BRUSH);
FillRect(dc(),&rcText,brush);
int move_num = (number-1)/2;
if (number % 2)
wsprintf(text,"%d %s",move_num+1,move_image);
else
wsprintf(text,"%d ... %s",move_num+1,move_image);
DrawText(dc(),text,strlen(text), &rcText, DT_LEFT | DT_WORDBREAK);
}
void Display::clear_move_area( WPDevContext &dc)
{
RECT rcText;
int start = width - TEXT_OFFSET;
SetRect(&rcText,start,MOVE_Y,start+width-5,
MOVE_Y+spacing);
// erase any previous text:
HBRUSH brush = GetStockObject(WHITE_BRUSH);
FillRect(dc(),&rcText,brush);
}
void Display::clear_status_line( WPDevContext &dc )
{
RECT rcText;
int start = width - TEXT_OFFSET;
SetRect(&rcText,start,MOVE_Y+spacing,width-5,
MOVE_Y+2*spacing);
HBRUSH brush = GetStockObject(WHITE_BRUSH);
// erase any previous contents of this field:
FillRect(dc(),&rcText,brush);
}
void Display::show_status( WPDevContext &dc, const Search::Statistics stats)
{
static char *images[] =
{
" ",
" ",
"Check! ",
"Mate! ",
"Stalemate",
"Draw! ",
"I resign!"
};
RECT rcText;
int start = width - TEXT_OFFSET;
SetRect(&rcText,start,MOVE_Y+spacing,width-5,
MOVE_Y+2*spacing);
HBRUSH brush = GetStockObject(WHITE_BRUSH);
// erase any previous contents of this field:
FillRect(dc(),&rcText,brush);
char text[30];
if ((stats.state == Search::Normal || stats.state == Search::Check) &&
(stats.value > Constants::BIG-100))
{
if (stats.value == Constants::BIG-1)
strcpy(text,"Checkmate!");
else
wsprintf(text,"Mate in %d!",(Constants::BIG-stats.value-1)/2);
}
else
wsprintf(text,"%s",images[stats.state]);
DrawText(dc(),text,strlen(text), &rcText, DT_LEFT | DT_WORDBREAK);
}
void Display::show_time( HWND handle, const time_t time,
const ColorType side )
{
// all straight Windows code - because we have no access to
// Windows++ classes
HDC hdc = GetDC(handle);
assert(hdc);
char time_str[20];
unsigned hours = time/3600L;
unsigned minutes = (time - (hours*3600L))/60L;
unsigned seconds = (time - (hours*3600L) - (minutes*60L));
// convert time to ASCII:
wsprintf(time_str,"%02d:%02d:%02d",
(int)hours,(int)minutes,(int)seconds);
RECT rcText, client_rect, text_rect;
GetClientRect( handle, &client_rect );
int width = client_rect.right - client_rect.left;
int vbase = TIME_Y;
TEXTMETRIC tm;
if (side == White)
{
SetRect(&text_rect,width-TEXT_OFFSET,vbase,width-5,vbase+spacing);
DrawText(hdc,"WHITE:",6,&text_rect,DT_LEFT);
SetRect(&rcText,width-TEXT_OFFSET,vbase+spacing,width-5,vbase+2*spacing);
}
else
{
SetRect(&text_rect,width-TEXT_OFFSET,vbase+2*spacing,width-5,
vbase+3*spacing);
DrawText(hdc,"BLACK:",6,&text_rect,DT_LEFT);
SetRect(&rcText,width-TEXT_OFFSET,vbase+3*spacing,width-5,vbase+4*spacing);
}
DrawText(hdc,time_str,lstrlen(time_str),&rcText,
DT_LEFT | DT_WORDBREAK);
BOOL ret = ReleaseDC(handle,hdc);
assert(ret);
}
void Display::clear_search_counts( WPDevContext &dc )
{
RECT rcText;
int start = width - TEXT_OFFSET;
SetRect(&rcText,start,PLY_Y,width-5,
PLY_Y+4*spacing);
HBRUSH brush = GetStockObject(WHITE_BRUSH);
// erase any previous contents of this field:
FillRect(dc(),&rcText,brush);
}
void Display::show_search_counts( HWND handle, const int ply,
const long nodes)
{
RECT rcText, client_rect, text_rect;
GetClientRect( handle, &client_rect );
int width = client_rect.right - client_rect.left;
int vbase = PLY_Y;
HDC hdc = GetDC(handle);
assert(hdc);
SetRect(&text_rect,width-TEXT_OFFSET,vbase,width-5,vbase+spacing);
char msg[20];
wsprintf(msg,"Ply: %d",ply);
DrawText(hdc,msg,lstrlen(msg),&text_rect,
DT_LEFT | DT_WORDBREAK);
text_rect.top += spacing;
text_rect.bottom += spacing;
DrawText(hdc,"Nodes:",6,&text_rect,
DT_LEFT | DT_WORDBREAK);
text_rect.top += spacing;
text_rect.bottom += spacing;
wsprintf(msg,"%ld",nodes);
DrawText(hdc,msg,lstrlen(msg),&text_rect,
DT_LEFT | DT_WORDBREAK);
BOOL ret = ReleaseDC(handle,hdc);
assert(ret);
}